package demo.issuetracker.dao.jpa;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.PostConstruct;
import javax.persistence.Query;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import demo.issuetracker.dao.jpa.JpaUser;

import demo.issuetracker.dao.UserDao;
import demo.issuetracker.entity.User;

@Component("userDao")
@Repository
@Transactional
public class JpaUserDao extends AbstractJpaDao<User> implements UserDao {
    @Override
    public void create(User user) {
        Object pk = user.primaryKey();
        if (pk == null) {
            pk = generatePrimaryKey();
            
            user.setUsername((String) pk);
        }

        em.persist(user);
    }

    @PostConstruct
    public void init() {
        // initialize the db with some initial data
    }

    /**
     * The "Create" or "Update" semantics of "CRUD"
     */
    public void createOrUpdate(User user) {
        if (user.primaryKey() == null) {
            create(user);
            return;
        }

        em.merge(user);
    }

    /**
     * Find by Primary key
     * 
     * The "read" operation of CRUD
     */
    public User findByPrimaryKey(String key) {
        if (key == null) {
            return null;
        }
        return em.find(JpaUser.class, key);
    }

    public User findByUsernameAndPassword(String username, String password) {
        Query qry = em.createQuery("from JpaUser user where user.username=:username and user.password=:password");
        qry.setParameter("username", username);
        qry.setParameter("password", JpaUser.encrypt(password));
        @SuppressWarnings("unchecked")
        List<JpaUser> userList = qry.getResultList();

        if (userList.size() == 0) {
            return null;
        }

        if (userList.size() == 1) {
            return userList.get(0);
        }

        throw new RuntimeException(
                "More than one user found for this username and password. Please contact the administrator. (username="
                        + username + ")");    
    }

    @Override
    public void delete(User user) {
        em.remove(user);
    }

    @Override
    public void update(User user) {
        em.merge(user);
    }


    /**
     * All Users. Display all Users in the system.
     * 
     * The "read" operation of CRUD
     */
    public List<User> findUserList(Map<String, Object> params) {
        Query qry = em.createQuery("from JpaUser user " /* where user.field1=:param1 and user.field2=:param2 */);
        // qry.setParameter("param1", param1);
        // qry.setParameter("param2", param2);
        @SuppressWarnings("unchecked")
        List<JpaUser> userList = qry.getResultList();

        return new ArrayList<User>(userList);
    }

    @Override
    public User newInstance() {
        User user = new JpaUser();
        
        return user;
    }

    private Object generatePrimaryKey() {
        return UUID.randomUUID().toString();
    }
    
    public <K> List<User> findBy(String name, K value) {
        return queryBySingleArgument("from JpaUser user where user." + name + " = :value", name, value);
    }
}// clickframes::version=1343412155::clickframes